import socket
import time
import MySQLdb
import signal

# This script listens for automation connections.
# It also monitors the AlarmHistory database for intellitap events
# 	which have not been delivered to automation yet.
# When an intellitap event is found, we deliver it to automation
#   but with the account # replaced by the Panel #.
# After delivery, we mark it as delivered by setting AckText.

conn = None
cursor = None
db = None


def main():
	db = MySQLdb.connect(host="192.168.100.47", user="jlucia@%", passwd="penril", db="AZSecurity")

	# Initial setup for listening socket for automation
	HOST = ''                 # Symbolic name meaning all available interfaces
	PORT = 50007              # Arbitrary non-privileged port
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.bind((HOST, PORT))
	s.listen(1)
	print "Waiting for connection..."
	conn, addr = s.accept()
	print 'Connected by', addr
	lastheartbeat = time.time()-58

	#Keep checking database for Intellitap Events
	cursor = db.cursor()

	while 1:
		time.sleep(1)
		cursor.execute("select ID, UnitID, AlarmTime, AutoMsg from AlarmHistory where AutoMsg like  '_93 %' and AckText is Null Order by ID")

		row = cursor.fetchone ()
		# print "%s, %x, %s, %s" % (row[0], row[1], row[2], row[3])
		if cursor.rowcount>0:
			ID = row[0]
			UNITID = ("0000" + hex(row[1])[2:10])[-5:-1]
			AutoMsg = row[3]
		else:
			AutoMsg = ""

		#***** Deliver to automation connection, wait for ACK
		if AutoMsg<>"":
			# Replace account number in AutoMsg with UntID
			# Change line 3 to line 8 so we know it was converted
			AutoMsg = AutoMsg[0:2] + "8 " + UNITID + AutoMsg[8:30]
			print time. asctime(),  ID, AutoMsg[1:50]

			try:  # clear receive buffer
				conn.settimeout(0.5)
				conn.recv(100)
			except:
				pass

			#***** send SIGNAL  to automation socked and wait for ACK or Timeout
			lastheartbeat = time.time()
			try: # Check Connection and wait for ACK
				conn.send(AutoMsg)
				conn.settimeout(5)
				data = conn.recv(1)
				if not data:
					#deal with broken connection
					print "Waiting for connection..."
					conn, addr = s.accept()
					print 'Connected by', addr
					lastheartbeat = time.time()-58
				else:
					if (data[0] == "\x06"):
						# Update ID in AlarmHistory once delivered to Automation
						print "ACK"
						cursor.execute ("""UPDATE AlarmHistory SET AckText = '1' WHERE ID = %s""", (ID))
						AutoMsg = ""
						lastheartbeat = time.time()
					else:
						print "NAK", data[0]
			except: # automation did not ACK the signal
				print "Timed Out"

		# ***** Send HEARTBEAT to Automation
		if time.time() - lastheartbeat > 60:
			# send heartbeat to automation
			#print "Heartbeat...",

			try: # Clear receive buffer
				conn.settimeout(0.5)
				conn.recv(100)
			except:
				pass

			try: # Send the Heartbeat and wait for ACK
				conn.send("3                  @\r")
				conn.settimeout(5)
				data = conn.recv(1)
				if not data:  #deal with broken connection
					print "Waiting for connection..."
					conn, addr = s.accept()
					print 'Connected by', addr
					lastheartbeat = time.time()-58
				else: # got the ACK
					if (data[0] == "\x06"):
						#print "ACK"
						lastheartbeat = time.time()
					else:
						print " Heartbeat NAK", data[0]
			except: # ACK not received from automation
				print "Heartbeat Timed Out"

	cursor.close()
	db.close()
	conn.close()
	print "Done."

if __name__ == "__main__":
	main()

